import { append as svgAppend, create as svgCreate } from 'tiny-svg';
import { uuid } from '@inbiz/utils';
import taskUserWhite from '../../assets/images/taskUserWhite.svg';
import countersignTask from '../../assets/images/countersignTask.svg';
// import externalTask from '../../assets/images/externalTask.svg';
import subProcess from '../../assets/images/subProcess.svg';

const xmlStr = '<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n' +
  '<bpmn:definitions xmlns:bpmn=\'http://www.omg.org/spec/BPMN/20100524/MODEL\' xmlns:xsi=\'http://www.w3.org/2001/XMLSchema-instance\' xmlns:bpmndi=\'http://www.omg.org/spec/BPMN/20100524/DI\' xmlns:omgdc=\'http://www.omg.org/spec/DD/20100524/DC\' xmlns:omgdi=\'http://www.omg.org/spec/DD/20100524/DI\' xmlns:dc=\'http://www.omg.org/spec/DD/20100524/DC\' xmlns:di=\'http://www.omg.org/spec/DD/20100524/DI\' xmlns:camunda=\'http://camunda.org/schema/1.0/bpmn\' xmlns:modeler=\'http://camunda.org/schema/modeler/1.0\' xmlns:activiti=\'http://activiti.org/bpmn\' id=\'Definitions_1v2uvsm\' targetNamespace=\'http://bpmn.io/schema/bpmn\' exporter=\'Camunda Modeler\' exporterVersion=\'5.1.0\' modeler:executionPlatform=\'Camunda Platform\' modeler:executionPlatformVersion=\'7.17.0\'>\n' +
  ' <bpmn:process id=\'Process_1\' isExecutable=\'true\'>\n' +
  '   <bpmn:extensionElements>\n' +
  '     <camunda:executionListener class="com.edoc2Flow.core.camunda.listener.Edoc2ProcessCompletedListenner" event="end" />\n' +
  '   </bpmn:extensionElements>\n' +
  '   <bpmn:startEvent id=\'start-C67C136C76100001EC28F17313501977\' name="开始" activiti:initiator="initiator">\n' +
  '     <bpmn:outgoing>flow-C67C136D75900001CECB161BB6901702</bpmn:outgoing>\n' +
  '   </bpmn:startEvent>\n' +
  '   <bpmn:userTask id=\'task-C67C136B7D3000014C62116076A64FD0\' name=\'发起人\' activiti:assignee="${initiator}">\n' +
  '     <bpmn:incoming>flow-C67C136D75900001CECB161BB6901702</bpmn:incoming>\n' +
  '   </bpmn:userTask>\n' +
  '   <bpmn:sequenceFlow id=\'flow-C67C136D75900001CECB161BB6901702\' sourceRef=\'start-C67C136C76100001EC28F17313501977\' targetRef=\'task-C67C136B7D3000014C62116076A64FD0\' />\n' +
  ' </bpmn:process>\n' +
  ' <bpmndi:BPMNDiagram id=\'BPMNDiagram_1\'>\n' +
  '   <bpmndi:BPMNPlane id=\'BPMNPlane_1\' bpmnElement=\'Process_1\'>\n' +
  '     <bpmndi:BPMNShape id=\'_BPMNShape_StartEvent_2\' bpmnElement=\'start-C67C136C76100001EC28F17313501977\'>\n' +
  '       <dc:Bounds x=\'100\' y=\'100\' width=\'30\' height=\'30\' />\n' +
  '       <bpmndi:BPMNLabel>\n' +
  '         <dc:Bounds x="100" y="133" width="30" height="30" />\n' +
  '       </bpmndi:BPMNLabel>\n' +
  '     </bpmndi:BPMNShape>\n' +
  '     <bpmndi:BPMNShape id=\'BPMNShape_firstTask\' bpmnElement=\'task-C67C136B7D3000014C62116076A64FD0\'>\n' +
  '       <dc:Bounds x=\'230\' y=\'85\' width=\'100\' height=\'60\' />\n' +
  '     </bpmndi:BPMNShape>\n' +
  '     <bpmndi:BPMNEdge id=\'BPMNEdge_flow-C67C136D75900001CECB161BB6901702\' bpmnElement=\'flow-C67C136D75900001CECB161BB6901702\'>\n' +
  '       <di:waypoint x=\'130\' y=\'115\' />\n' +
  '       <di:waypoint x=\'230\' y=\'115\' />\n' +
  '     </bpmndi:BPMNEdge>\n' +
  '   </bpmndi:BPMNPlane>\n' +
  ' </bpmndi:BPMNDiagram>\n' +
  '</bpmn:definitions>';

const startEventId = 'start-C67C136C76100001EC28F17313501977';
const firstTaskId = 'task-C67C136B7D3000014C62116076A64FD0';
const firstFlowId = 'flow-C67C136D75900001CECB161BB6901702';

const flowAction = {
  // 线
  type: 'global-connect-tool',
  action: ['bpmn:SequenceFlow', 'tools', 'bpmn-custom-palette bpmn-custom-palette-flow', '连接线'],
};

const customShapeAction = [
  // shape
  // type, group, className, title, options
  {
    type: 'create.start-event',
    action: ['bpmn:StartEvent', 'event', 'bpmn-custom-palette bpmn-custom-palette-start', '开始'],
  },
  {
    type: 'create.end-event',
    action: ['bpmn:EndEvent', 'event', 'bpmn-custom-palette bpmn-custom-palette-end', '结束'],
  },
  {
    type: 'create.userTask',
    action: [
      'bpmn:UserTask',
      'task',
      'bpmn-custom-palette bpmn-custom-palette-user-task',
      '用户任务',
    ],
  },
  {
    type: 'create.countersignTask',
    action: [
      'bpmn:ManualTask',
      'task',
      'bpmn-custom-palette bpmn-custom-palette-countersign-task',
      '会签任务',
    ],
  },
  {
    type: 'create.externalTask',
    action: [
      'bpmn:BusinessRuleTask',
      'task',
      'bpmn-custom-palette bpmn-custom-palette-external-task',
      '外部任务',
    ],
  },

  {
    type: 'create.includeBranch',
    action: [
      'bpmn:ExclusiveGateway',
      'task',
      'bpmn-custom-palette bpmn-custom-palette-include-branch',
      '串行分支',
    ],
  },
  {
    type: 'create.parallelBranch',
    action: [
      'bpmn:ParallelGateway',
      'task',
      'bpmn-custom-palette bpmn-custom-palette-parallel-branch',
      '并行分支',
    ],
  },
  {
    type: 'create.serialBranch',
    action: [
      'bpmn:InclusiveGateway',
      'task',
      'bpmn-custom-palette bpmn-custom-palette-serial-branch',
      '包含分支',
    ],
  },
  {
    type: 'create.subProcess',
    action: [
      'bpmn:Task',
      'task',
      'bpmn-custom-palette bpmn-custom-palette-sub-process',
      '子流程',
    ],
  },
];

const customFlowAction = [flowAction];

const batchCreateCustom = (actions: any[], fn: any) => {
  const customs: any = {};
  actions.forEach((item: { [x: string]: any }) => {
    customs[item['type']] = fn(...item['action']);
  });
  return customs;
};

// 自定义元素的配置
const customConfig: any = {
  'bpmn:StartEvent': {
    title: '开始',
    attr: {
      x: 0,
      y: 0,
      width: 30,
      height: 30,
    },
  },
  'bpmn:EndEvent': {
    title: '结束',
    attr: {
      x: 0,
      y: 0,
      width: 30,
      height: 30,
    },
  },
  'bpmn:UserTask': {
    title: '用户任务',
    attr: {
      x: 0,
      y: 0,
      width: 100,
      height: 60,
    },
  },
  'bpmn:BusinessRuleTask': {
    title: '外部任务',
    attr: {
      x: 0,
      y: 0,
      width: 100,
      height: 60,
    },
  },
  'bpmn:InclusiveGateway': {
    imgPath: 'serialBranch',
    title: '包含分支',
    attr: {
      width: 50,
      height: 50,
    },
  },
  'bpmn:ParallelGateway': {
    imgPath: 'parallelBranch',
    title: '并行分支',
    attr: {
      width: 50,
      height: 50,
    },
  },
  'bpmn:ExclusiveGateway': {
    imgPath: 'includeBranch',
    title: '串行分支',
    attr: {
      width: 50,
      height: 50,
    },
  },
  'bpmn:CallActivity': {
    title: '子流程',
    attr: {
      x: 0,
      y: 0,
      width: 100,
      height: 60,
    },
  },
  'bpmn:SequenceFlow': {
    attr: {},
  },
  'label': {
    attr: {},
  },
};

const generateMixed = (n: number) => {
  var chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
  var res = '';
  for (var i = 0; i < n; i++) {
    var id = Math.floor(Math.random() * 36);
    res += chars[id];
  }
  return res;
};

const formatSvgText = (assignee: any[] | string) => {
  let _assignee = assignee;
  if (typeof assignee == 'string') {
    try {
      _assignee = JSON.parse(assignee);
    } catch (error) {
      return '';
    };
  }
  if (!_assignee?.[0]?.name && !_assignee?.[0]?.text) {
    return ''
  };
  let name = '';
  if (_assignee?.length > 0) {
    let _name = _assignee?.[0]?.name || _assignee?.[0]?.text?.split('(')?.[0] || '';
    if (_assignee?.length == 1) {
      name = formatText(_name) || '';
    } else {
      name = _name?.slice(0, 5) + '...';
    };
  };
  return name;
};

const isChineseChar = (str: string) => {
  var reg = /[\u4E00-\u9FA5\uF900-\uFA2D]/;
  return reg.test(str);
};

const isLetterOrNumber = (str: string) => {
  var reg = /^[A-Za-z0-9!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]*$/;
  return reg.test(str);
};

const formatText = (text: string) => {
  if (!text || typeof text != 'string') {
    return '';
  };
  let weightNumber: number = 0;
  let typeArray: number[] = [];
  for (let i = 0; i < text.length; i++) {
    const element = text[i];
    if (isLetterOrNumber(element)) {
      weightNumber = weightNumber + 1;
      typeArray.push(1);
    };
    if (isChineseChar(element)) {
      weightNumber = weightNumber + 2;
      typeArray.push(2);
    };
  };
  if (weightNumber <= 6) {
    return text;
  } else {
    let returnString: string = '';
    let _weightNumber: number = 0;
    for (let j = 0; j < typeArray.length; j++) {
      const element = typeArray[j];
      _weightNumber = _weightNumber + element;
      returnString = returnString + text[j];
      if (_weightNumber == 6) {
        return returnString + '...';
      } else if (_weightNumber == 7) {
        return returnString.slice(0, returnString?.length - 1) + '...';
      }
    }
  };
};

const getAssigneetext = (data: any) => {
  const type = data?.baseInfo?.performerType;
  switch (type) {
    case 'user':
    case 'userGroup':
    case 'position':
    case 'dept':
      return formatSvgText(data?.baseInfo?.assignee);
    case 'vars':
      return formatText(data?.baseInfo?.assignee);
    case '${initiator}':
      return formatText('发起人');
    case '${scriptServiceImpl.getInitiatorSupervisor(execution)}':
      return formatText('发起人直属主管');
    case '${scriptServiceImpl.getInitiatorDeptManager(execution)}':
      return formatText('发起人部门主管');
    case '${scriptServiceImpl.getPrevActivitySupervisor(execution)}':
      return formatText('前一步直属主管');
    case '${scriptServiceImpl.getPrevActivityDeptManager(execution)}':
      return formatText('前一步部门主管');
    default:
      return ''
  }
};

const formatEventLabel = (name: string) => {
  let weightNumber: number = 0;
  let nameIndex: number = 0;
  let text: string = '';
  while (weightNumber < 4 && nameIndex < name?.length) {
    if (isChineseChar(name[nameIndex])) {
      weightNumber += 2;
    };
    if (isLetterOrNumber(name[nameIndex])) {
      weightNumber += 1;
    };
    text = text + name[nameIndex]
    nameIndex += 1;
  };
  return nameIndex < name?.length ? text + '...' : text;
};

function getSvg(parentNode: Element, element: any, isCurrentViewElement?: boolean, isCurrentNode?: boolean, isCurrentHoverViewElement?: boolean, isReturnBackViewElement?: boolean) {
  let taskType = element?.businessObject?.name;
  let imgUrl: string = '';
  const _id = element?.id;
  const _type = element?.type;
  if (_id == firstTaskId) {
    imgUrl = taskUserWhite;
  } else if (_type == 'bpmn:CallActivity') {
    imgUrl = subProcess;
  } else if (_id?.startsWith('task')) {
    imgUrl = taskUserWhite;
  } else if (_id?.startsWith('ctSign')) {
    imgUrl = countersignTask;
  };
  const customElementbox1: SVGRectElement = svgCreate('rect', {
    rx: 9,
    tx: 9,
    width: 100,
    height: 60,
    x: 0,
    y: 0,
    fill: isCurrentViewElement ? '#eeeeee' : isCurrentHoverViewElement ? '#f5f5f5' : 'rgb(255, 255, 255)',
    stroke: isReturnBackViewElement ? '#ff1313' : isCurrentNode ? 'rgb(61, 200, 133)' : 'rgb(215, 218, 229)',
    strokeWidth: 1,
  });
  svgAppend(parentNode, customElementbox1);
  const customElementType: SVGCircleElement = svgCreate('circle', {
    r: 9,
    stroke: '#ffffff',
    cx: 50,
    cy: 43,
    fill: '#1989fa',
  });
  svgAppend(parentNode, customElementType);
  const customElementIcon: SVGImageElement = svgCreate('image', {
    width: 18,
    height: 18,
    x: _type == 'bpmn:CallActivity' ? 42 : 41,
    y: 34,
    href: imgUrl,
  });
  svgAppend(parentNode, customElementIcon);
  const text1: SVGTextElement = svgCreate('text', {
    x: 50,
    y: 20,
    'font-size': '14',
    fill: '#666666',
    textAnchor: 'middle',
    dominantBaseline: 'middle',
  });
  text1.innerHTML = taskType;
  svgAppend(parentNode, text1);
  return [customElementbox1, customElementType, customElementIcon, text1];
};

const customModdleActivitiPackage = {
  'name': 'activiti',
  'uri': 'http://activiti.org/bpmn',
  'prefix': 'activiti',
  'xml': {
    'tagAlias': 'lowerCase',
  },
  'types': [
    {
      'name': 'In',
      'isAbstract': true,
      'extends': [],
      'properties': [
        {
          'name': 'activiti:in',
          'isAttr': true,
          'type': 'activiti:in'
        }
      ]
    },
    {
      'name': 'Out',
      'isAbstract': true,
      'extends': [],
      'properties': [
        {
          'name': 'activiti:out',
          'isAttr': true,
          'type': 'activiti:out'
        }
      ]
    }
  ]
};

const addMemberKey = (members: any[]) => {
  if (members?.some((item) => !item?.key)) {
    return members?.map((item1) => {
      return {
        key: item1?.memberType == 0 ? `user-${item1?.identityId}` : item1?.memberType == 3 ? `group-${item1?.identityId}` : item1?.memberType == 4 ? `position-${item1?.identityId}` : `department-${item1?.identityId}`,
        id: item1?.guid,
        identityid: item1?.identityId,
        name: item1?.text?.split('(')?.[0],
        useremail: item1?.userEmail,
        account: item1?.account,
        memberarea: item1?.memberType,
        ...item1,
      };
    });
  } else {
    return members;
  };
};

const getInitialRestartValue = (buttonSetting: any) => {
  let _initialValue: string[] = [];
  if (buttonSetting?.isReturnStarter) {
    _initialValue?.push('isReturnStarter');
  };
  if (buttonSetting?.isCdirectBack) {
    _initialValue?.push('isCdirectBack');
  };
  return _initialValue;
};

const defaultStrategyValue = {
  msgRule: { reminderTime: 0, unit: '0' },
  msgType: 'interval',
  pushRule: { reminderTime: 0, unit: '0' },
}

const defaultFirstTaskActions = [
  {
    id: 'button' + uuid(20, 60),
    action: 'initiate',
    name: 'processButton.initiate',
    type: 'initiate',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: true,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'withDraw',
    name: 'processButton.withDraw',
    type: 'withDraw',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'isUrge',
    name: 'processButton.isUrge',
    type: 'isUrge',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'print',
    name: 'processButton.print',
    type: 'print',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'termination',
    name: 'processButton.termination',
    type: 'termination',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'draft',
    name: 'processButton.draft',
    type: 'draft',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
]

const defaultUserTaskActions = [
  {
    id: 'button' + uuid(20, 60),
    action: 'approve',
    name: 'processButton.approve',
    type: 'approve',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: true,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'returnsBack',
    name: 'processButton.returnsBack',
    type: 'returnsBack',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'assign',
    name: 'processButton.assign',
    type: 'assign',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'cancel',
    name: 'processButton.cancel',
    type: 'cancel',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'plusSign',
    name: 'processButton.plusSign',
    type: 'plusSign',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'print',
    name: 'processButton.print',
    type: 'print',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
];

const defaultCtSignTaskActions = [
  {
    id: 'button' + uuid(20, 60),
    action: 'approve',
    name: 'processButton.approve',
    type: 'approve',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: true,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'returnsBack',
    name: 'processButton.returnsBack',
    type: 'returnsBack',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'plusSign',
    name: 'processButton.plusSign',
    type: 'plusSign',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'print',
    name: 'processButton.print',
    type: 'print',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
]

const defaultPlussignActions = [
  {
    id: 'button' + uuid(20, 60),
    action: 'approve',
    name: '同意',
    type: 'approve',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: true,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'returnsBack',
    name: '退回',
    type: 'returnsBack',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: true,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'cancel',
    name: '终止',
    type: 'cancel',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: true,
  },
  {
    id: 'button' + uuid(20, 60),
    action: 'print',
    name: '打印',
    type: 'print',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: false,
  },
];

const defaultReturnsBackButtonConfig = [
  {
    action: 'returnStarter',
    actionLang: 'processButton.returnsStarter',
    text: 'processButton.returnsStarter',
    title: '重新依次审批，例流程为A-B-C，C退回至A，，则为C-A-B-C，且每个节点都会触发对应消息通知和业务规则',
    enable: true,
  },
  {
    action: 'cdirectBack',
    actionLang: 'processButton.returnsStartModify',
    text: 'processButton.returnsStartModify',
    title: '从当前节点审批，例流程为A-B-C，C退回至A，则为C-A-C，且过程不再触发消息通知和业务规则',
    enable: false,
  },
];

const defaultPlusSignButtonConfig = [
  {
    action: 'approve',
    actionLang: 'processButton.approve',
    text: 'processButton.approve',
    enable: true,
    disabled: true,
  },
  {
    action: 'cancel',
    actionLang: 'processButton.cancel',
    text: 'processButton.cancel',
    enable: false,
    disabled: false,
  },
];

const getInitButtons = (type: string, buttons: any[]) => {
  switch (type) {
    case 'firstTask':
      let _firstTaskButtons = buttons;
      if (!_firstTaskButtons || _firstTaskButtons && _firstTaskButtons?.length == 0) {
        _firstTaskButtons = defaultFirstTaskActions
      } else {
        if (buttons?.every((item) => item?.action != 'initiate')) {
          _firstTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'initiate',
            name: 'processButton.initiate',
            type: 'initiate',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: true,
          });
        };
        if (buttons?.every((item) => item?.action != 'withDraw')) {
          _firstTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'withDraw',
            name: 'processButton.withDraw',
            type: 'withDraw',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: false,
          });
        };
        if (buttons?.every((item) => item?.action != 'print')) {
          _firstTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'print',
            name: 'processButton.print',
            type: 'print',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: false,
          });
        };
        if (buttons?.every((item) => item?.action != 'cancel')) {
          _firstTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'cancel',
            name: 'processButton.cancel',
            type: 'cancel',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: false,
          });
        };
        if (buttons?.every((item) => item?.action != 'draft')) {
          _firstTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'draft',
            name: 'processButton.draft',
            type: 'draft',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: false,
          });
        };
        if (buttons?.every((item) => item?.action != 'isUrge')) {
          _firstTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'isUrge',
            name: 'processButton.isUrge',
            type: 'isUrge',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: false,
          });
        };
      }
      return _firstTaskButtons;
    case 'userTask':
      let _userTaskButtons = buttons;
      if (!_userTaskButtons || _userTaskButtons && _userTaskButtons?.length == 0) {
        _userTaskButtons = defaultUserTaskActions;
      } else {
        if (buttons?.every((item) => item?.action != 'approve')) {
          _userTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'approve',
            name: 'processButton.approve',
            type: 'approve',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: true,
          });
        };
        if (buttons?.every((item) => item?.action != 'returnsBack')) {
          _userTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'returnsBack',
            name: 'processButton.returnsBack',
            type: 'returnsBack',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: false,
          });
        };
        if (buttons?.every((item) => item?.action != 'assign')) {
          _userTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'assign',
            name: 'processButton.assign',
            type: 'assign',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: false,
          });
        };
        if (buttons?.every((item) => item?.action != 'cancel')) {
          _userTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'cancel',
            name: 'processButton.cancel',
            type: 'cancel',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: false,
          });
        };
        if (buttons?.every((item) => item?.action != 'plusSign')) {
          _userTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'plusSign',
            name: 'processButton.plusSign',
            type: 'plusSign',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: false,
          });
        };
        if (buttons?.every((item) => item?.action != 'print')) {
          _userTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'print',
            name: 'processButton.print',
            type: 'print',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: false,
          });
        };
      };
      return _userTaskButtons;
    case 'ctSignTask':
      let _ctSignTaskButtons = buttons;
      if (!_ctSignTaskButtons || _ctSignTaskButtons && _ctSignTaskButtons?.length == 0) {
        _ctSignTaskButtons = defaultCtSignTaskActions;
      } else {
        if (buttons?.every((item) => item?.action != 'approve')) {
          _ctSignTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'approve',
            name: 'processButton.approve',
            type: 'approve',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: true,
          });
        };
        if (buttons?.every((item) => item?.action != 'returnsBack')) {
          _ctSignTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'returnsBack',
            name: 'processButton.returnsBack',
            type: 'returnsBack',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: false,
          });
        };
        if (buttons?.every((item) => item?.action != 'cancel')) {
          _ctSignTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'cancel',
            name: 'processButton.cancel',
            type: 'cancel',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: false,
          });
        };
        if (buttons?.every((item) => item?.action != 'print')) {
          _ctSignTaskButtons.push({
            id: 'button' + uuid(20, 60),
            action: 'print',
            name: 'processButton.print',
            type: 'print',
            bgColor: 'rgba(25,137,250,1)',
            fontColor: 'rgba(255,255,255,1)',
            enable: false,
          });
        };
      };
      return _ctSignTaskButtons;
    default:
      return [];
  };
};

const canOperate1 = (item: { id: string; type: string; }) => {
  return item?.id != firstTaskId && item?.type != 'bpmn:StartEvent' && item?.id != firstFlowId && item?.type != 'bpmn:EndEvent' && item?.type != 'label' && item?.type != 'bpmn:SequenceFlow';
};

const canOperate2 = (item: { id: string; type: string; }) => {
  return item?.id != firstTaskId && item?.type != 'bpmn:StartEvent' && item?.id != firstFlowId && item?.type != 'label';
};

const unique = (arr: any[]) => {
  return Array.from(new Set(arr));
};

const getJumpRuleValue = (data: any) => {
  let result: string[] = [];
  if (data?.samePrevStartActSkip) {
    result?.push('samePrevStartActSkip');
  };
  if (data?.samePrevActSkip) {
    result?.push('samePrevActSkip');
  };
  if (data?.samePrevAllActSkip) {
    result?.push('samePrevAllActSkip');
  };
  if (data?.batchApproval) {
    result?.push('batchApproval');
  };
  return result;
};

const setJumpRuleValue = (jumpRule: string[], jumpRuleItem: string) => {
  if (jumpRule?.includes(jumpRuleItem)) {
    return true;
  } else {
    return false;
  };
};

const setUserTaskXmlActivitiProps = (baseInfo: { performerCategory: string; performerType: string; assignee: any; }) => {
  const performerCategory = baseInfo?.performerCategory || '';
  const performerType = baseInfo?.performerType || '';
  const assignee = baseInfo?.assignee ? baseInfo?.assignee : performerType == 'vars' ? '' : [];

  switch (performerCategory) {
    // 处理
    case 'assigeenCategory':
      switch (performerType) {
        case '${initiator}':
          return '${initiator}';
        case 'user':
          return assignee?.[0]?.guid || assignee?.[0]?.id || '';
        default:
          return '${assignee}';
      };
    // 待领
    case 'cliamCategory':
      switch (performerType) {
        case 'user':
          return assignee?.map((item: { guid?: string, id?: string }) => {
            if (item?.guid) {
              return item?.guid;
            } else {
              return item?.id;
            };
          })?.join(',');
        case 'userGroup':
          return "${scriptServiceImpl.getUsersByGroup(\' + " + (assignee?.[0]?.guid || assignee?.[0]?.id || '') + " + \')}";
        case 'position':
          return "${scriptServiceImpl.getUsersByPosition(\' + " + (assignee?.[0]?.guid || assignee?.[0]?.id || '') + " + \')}";
        case 'dept':
          return "${scriptServiceImpl.getUsersByDeptId(\' + " + (assignee?.[0]?.guid || assignee?.[0]?.id || '') + " + \'))}";
        case 'vars':
          return "${scriptServiceImpl.getUsersByVars('" + assignee + "',execution)}";
        default:
          return performerType;
      }
    default:
      return '';
  };
};

const setUserTaskXmlCollectionProps = (baseInfo: { performerType: string; assignee: any; }) => {
  const performerType = baseInfo?.performerType || '';
  const assignee = baseInfo?.assignee || [];
  switch (performerType) {
    case 'userGroup':
      return '${scriptServiceImpl.getUsersByGroup(' + '\'' + (assignee?.[0]?.guid || assignee?.[0]?.id || '') + '\'' + ')}';
    case 'position':
      return '${scriptServiceImpl.getUsersByPosition(' + '\'' + (assignee?.[0]?.guid || assignee?.[0]?.id || '') + '\'' + ')}';
    case 'dept':
      return '${scriptServiceImpl.getUsersByDeptId(' + '\'' + (assignee?.[0]?.guid || assignee?.[0]?.id || '') + '\'' + ')}';
    case 'vars':
      return "${scriptServiceImpl.getUsersByVars('" + (assignee || '') + "',execution)}";
    default:
      return performerType;
  };
};

const setCtSignTaskXmlCollectionProps = (baseInfo: { performerType: string; assignee: any; }) => {
  const performerType = baseInfo?.performerType || '';
  const assignee = typeof baseInfo?.assignee == 'string' ? JSON.parse(baseInfo?.assignee) : (baseInfo?.assignee || []);
  switch (performerType) {
    case 'user':
      return "${scriptServiceImpl.setUsers('" + assignee?.map((item: { id: string }) => item?.id)?.join(',') + "')}";
    case 'userGroup':
      return "${scriptServiceImpl.getUsersByGroup('" + (assignee?.[0]?.id || '') + "')}";
    case 'position':
      return "${scriptServiceImpl.getUsersByPosition('" + (assignee?.[0]?.id || '') + "')}";
    case 'dept':
      return "${scriptServiceImpl.getUsersByDeptId('" + (assignee?.[0]?.id || '') + "')}";
    case 'vars':
      return "${scriptServiceImpl.getUsersByVars('" + (assignee || '') + "',execution)}";
    default:
      return '';
  };
};

const setUserTaskBusinessObject = (baseInfo: { performerCategory: string; taskName: string; performerType: string; assignee: any; }) => {
  const performerCategory = baseInfo?.performerCategory;
  const name = baseInfo?.taskName;
  const key = performerCategory == 'assigeenCategory' ? 'activiti:assignee' : 'activiti:candidateUsers';
  const deleteKey = performerCategory == 'assigeenCategory' ? 'activiti:candidateUsers' : 'activiti:assignee';
  const value = setUserTaskXmlActivitiProps(baseInfo);
  return {
    name,
    [key]: value,
    [deleteKey]: '',
  };
};

const setProLconStringToObject = (proLconString: string) => {
  let proLconObject: any = {
    type: '',
    color: '',
  }
  if (proLconString && proLconString?.trim().startsWith('v6_font_family')) {
    const [, v1, v2] = proLconString.split(' ');
    proLconObject = {
      type: v1 || '',
      color: v2 || '',
    };
  } else {
    proLconObject = {
      type: 'icon-process-morentubiao',
      color: '#fc9637',
    }
  }
  return proLconObject;
};

const setProLconObjectToString = (proLconObject: { type: string, color: string }) => {
  return `v6_font_family ${proLconObject?.type || ''} ${proLconObject?.color || ''}`.trim();
};

const formSpecialCharRegVerification = () => ({
  validator(_: any, value: string) {
    const regExp = /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/g;
    if (regExp.test(value)) {
      return Promise.reject(new Error('请勿输入特殊字符'));
    } else {
      return Promise.resolve();
    }
  },
});

const formNameVerification = [
  { required: true, message: '名称不能为空' },
  { whitespace: true, message: '名称不能为空' },
  { max: 50, message: '名称长度不能超过50字符' },
];

const formActivityNoVerification = [
  // { required: true, message: '任务标识不能为空' },
  { max: 50, message: '标识长度不能超过50字符' },
  {
    validator(_: any, value: string) {
      const regExp = /[!@#$%^&*()+\=[\]{};':"\\|,.<>/?]/g;
      if (regExp.test(value)) {
        return Promise.reject(new Error('请勿输入特殊字符'));
      } else {
        return Promise.resolve();
      }
    },
  }
];

const buttonTableActionsEnum = {
  initiate: '发起',
  approve: '同意',
  returnsBack: '退回',
  assign: '指派',
  cancel: '终止',
  withDraw: '撤回',
  plusSign: '加签',
  print: '打印',
  isUrge: '催办',
  draft: '保存到草稿',
  custom: '自定义',
};

const defaultUserTask = [
  {
    activityId: 'task-C67C136B7D3000014C62116076A64FD0',
    baseInfo: {
      activityNo: 'firstTask',
      taskName: '发起人',
      assignee: [],
    },
    buttonSetting: {
      actions: defaultFirstTaskActions,
      inWithDraw: false,
      withdrawRule: 'openWithdrawal',
    },
    assembly: [{
      controlId: '',
      authority: '',
    }],
    senior: {
      jumpRule: [],
      automaticUrge: false,
      automaticIntervar: {
        msgType: 'interval',
        msgRule: {
          reminderTime: '0',
          unit: '0',
        },
        pushRule: {
          reminderTime: '0',
          unit: '0',
        },
      },
      isPushReachMsg: false,
      isPushCandidateMsg: false,
      isPushAssignMsg: false,
      isPushReturnMsg: false,
      isPushTimeOutMsg: false,
      isPushUrgingMsg: false,
      isPushCancelMsg: false,
      isPushEndMsg: false,
    },
  }
];

const defaultSequenceFlowData = [{
  activityId: 'flow-C67C136D75900001CECB161BB6901702',
  remark: '',
  conditionExpression: [],
}];

const defaultProcessDefinition = (processData?: any) => {
  return {
    processDefinitionKey: processData?.processKey || '',
    processName: processData?.name || '',
    proLcon: processData?.proLcon || 'v6_font_family icon-process-morentubiao #fc9637',
    groupId: processData?.groupId || '1',
    jumpRule: processData?.jumpRule ?? [],
    abstract: processData?.abstract ?? [],
    isReturnToDesignator: processData?.isReturnToDesignator ?? false,
    pushReachMsg: processData?.pushReachMsg ?? true,
    tanTemplate: processData?.tanTemplate ?? null,
    pushCandidateMsg: processData?.pushCandidateMsg ?? true,
    tCandidateTemplate: processData?.tCandidateTemplate ?? null,
    pushAssignMsg: processData?.pushAssignMsg ?? true,
    tAssignTemplate: processData?.tAssignTemplate ?? null,
    pushReturnMsg: processData?.pushReturnMsg ?? true,
    trnTemplate: processData?.trnTemplate ?? null,
    pushTimeOutMsg: processData?.pushTimeOutMsg ?? true,
    ttonTemplate: processData?.ttonTemplate ?? null,
    pushEndMsg: processData?.pushEndMsg ?? true,
    pcnTemplate: processData?.pcnTemplate ?? null,
    pushUrgingMsg: processData?.pushUrgingMsg ?? true,
    reminderMailTemplate: processData?.reminderMailTemplate ?? null,
    isPushCancelMsg: processData?.isPushCancelMsg ?? true,
    tCancelProcessTemplate: processData?.tCancelProcessTemplate ?? null,
  }
};

const defaultNewUserTask = (id: string, name: string) => {
  return {
    activityId: id,
    baseInfo: {
      isCounterSignNode: false,
      activityNo: '',
      taskName: name,
      performerCategory: 'assigeenCategory',
      performerType: 'user',
      expression: '',
      assignee: [],
      vars: '',
      minReplyNumber: '',
      copying: false,
      ccCategory: '0',
      ccRules: true,
      ccMember: '',
    },
    buttonSetting: {
      actions: defaultUserTaskActions,
    },
    assembly: [],
    senior: {
      jumpRule: [],
      automaticUrge: false,
      automaticIntervar: {
        msgType: 'interval',
        msgRule: {
          reminderTime: '0',
          unit: '0',
        },
        pushRule: {
          reminderTime: '0',
          unit: '0',
        },
      },
      isPushReachMsg: false,
      isPushCandidateMsg: false,
      isPushAssignMsg: false,
      isPushReturnMsg: false,
      isPushTimeOutMsg: false,
      isPushUrgingMsg: false,
      isPushCancelMsg: false,
      isPushEndMsg: false,
    },
  }
}

const defaultCtSignTask = (id: string, name: string) => {
  return {
    activityId: id,
    baseInfo: {
      isCounterSignNode: true,
      activityNo: '',
      taskName: name,
      performerCategory: 'assigeenCategory',
      performerType: 'user',
      expression: '',
      assignee: [],
      vars: '',
      isSequential: false,
      probability: 100,
      copying: false,
      ccCategory: '0',
      ccRules: true,
      ccMember: '',
    },
    buttonSetting: {
      actions: defaultCtSignTaskActions,
    },
    assembly: [],
    senior: {
      jumpRule: [],
      automaticUrge: false,
      automaticIntervar: {
        msgType: 'interval',
        msgRule: {
          reminderTime: '0',
          unit: '0',
        },
        pushRule: {
          reminderTime: '0',
          unit: '0',
        },
      },
      isPushReachMsg: false,
      isPushCandidateMsg: false,
      isPushAssignMsg: false,
      isPushReturnMsg: false,
      isPushTimeOutMsg: false,
      isPushUrgingMsg: false,
      isPushCancelMsg: false,
      isPushEndMsg: false,
    },
  }
};

const defaultSubProcess = (id: string) => {
  return {
    activityId: id,
    activityNo: '',
    callActivitiID: '',
    callActiviti: {
      id: '',
      text: '',
    },
    psVariables: [],
  }
};

const getConditionExpressionText = (conditionExpression: any[]) => {
  let text: string = '';
  conditionExpression?.map((item) => {
    text = text + `${item?.leftBracket || ''}${item?.varName || ''}${item?.symbolicLogic || ''}${item?.compareValue || ''}${item?.rightBracket || ''}${item?.logic || ''}`
  });
  return `[${text}]`;
};

const getExpressionArray = (expression: any[]) => {
  if (expression?.some((item) => !item?.id)) {
    return expression?.map((item) => {
      return {
        ...item,
        id: 'condition' + uuid(20, 60),
      };
    });
  } else {
    return expression;
  };
};

const getProcessIdFromSearch = (key?: string) => {
  const search = location.search;
  const paramsArray = search.slice(1).split('&');
  const paramsObject: any = {};
  paramsArray.forEach((item) => {
    const keyValue = item.split('=');
    paramsObject[keyValue[0]] = keyValue[1];
  });
  return key ? paramsObject[key] : paramsObject;
};

const addCustomButton = (buttonFieldsRef: any) => {
  const _customButton = buttonFieldsRef?.current?.customValue;
  buttonFieldsRef?.current?.onCustomChange([..._customButton, {
    id: 'button' + uuid(20, 60),
    action: 'custom',
    name: 'processButton.custom',
    type: 'custom',
    bgColor: 'rgba(25,137,250,1)',
    fontColor: 'rgba(255,255,255,1)',
    enable: true,
  }]);
};

const getInitUserTask = (processData: any) => {
  let userTask = JSON.parse(processData?.extPropJson)?.userTask || [];
  const fieldPerm = processData?.fieldPerm || [];
  if (fieldPerm && fieldPerm?.length > 0) {
    userTask = userTask?.map((item) => {
      let _item = fieldPerm?.find((item1) => item1?.activityId == item?.activityId);
      if (_item) {
        return {
          ...item,
          assembly: _item?.fields
        };
      } else {
        return item;
      };
    });
  };
  return userTask?.length == 0 ? null : userTask;
};

export {
  getProcessIdFromSearch,
  addMemberKey,
  customConfig,
  xmlStr,
  customShapeAction,
  customFlowAction,
  batchCreateCustom,
  generateMixed,
  getSvg,
  startEventId,
  firstTaskId,
  firstFlowId,
  customModdleActivitiPackage,
  formatSvgText,
  defaultFirstTaskActions,
  defaultStrategyValue,
  defaultPlussignActions,
  getInitialRestartValue,
  defaultUserTaskActions,
  defaultCtSignTaskActions,
  canOperate1,
  canOperate2,
  unique,
  getJumpRuleValue,
  setJumpRuleValue,
  setUserTaskXmlActivitiProps,
  setUserTaskBusinessObject,
  setUserTaskXmlCollectionProps,
  setCtSignTaskXmlCollectionProps,
  setProLconStringToObject,
  setProLconObjectToString,
  formSpecialCharRegVerification,
  formNameVerification,
  formActivityNoVerification,
  buttonTableActionsEnum,
  defaultUserTask,
  defaultSequenceFlowData,
  defaultProcessDefinition,
  getConditionExpressionText,
  getExpressionArray,
  defaultNewUserTask,
  defaultCtSignTask,
  defaultSubProcess,
  getInitButtons,
  defaultReturnsBackButtonConfig,
  defaultPlusSignButtonConfig,
  addCustomButton,
  getInitUserTask,
};